//onemax GA problem-depended class
//$Id: onemax_ga.h 718 2012-06-04 17:02:38Z Oleg.Bulychov@gmail.com $
#pragma once

#include "projects/onemax/onemax.h"
#include "solvers/ga/ga_common.h"
//__________________________________________________________________________________
//__________________________________________________________________________________
template<>
struct solution<OneMax_Solution, ga_tag>:
    public OneMax_Solution
{
    typedef solution<OneMax_Solution, ga_tag> OneMax_Solution_GA;
public:
    mutable double wheel_sector_;

    template<class E>
    void cross(E* env, random_generator& rnd, OneMax_Solution_GA& genome)
    {//:simple one point crossover
        ASSERT_(data_.size());
        ASSERT_(data_.size() == genome.data_.size());
        size_t size = data_.size();
        size_t j = rnd.next_SizeT(size);
        for (size_t i = j; i < size; ++i)
        {
            std::swap(data_[i], genome.data_[i]);
        }
        changed_ = genome.changed_ = true;
    }

    template<class E>
    void mutate(E* env, random_generator& rnd, double mutationProbability)
    {
        size_t size = data_.size();
        for (size_t i = 0; i < size; ++i)
        {
            if (rnd.next_Double() < mutationProbability)
            {
                data_[i] = !data_[i];
                changed_ = true;
            }
        }
    }

    int get_Fitness() const { return get_Cost(); }
};



template<class E, class X>
void OneMax_History::update(int step, int rank, GA<X>& s, E* env)
{
    GA<X>::TSolution** sol = s.get_Population();
    int psize = s.get_Population_Size();

    hist_[rank].sol_.resize(hist_[rank].sol_.size() + 1);
    std::vector<OneMax_Solution>& arr = hist_[rank].sol_.back();
    arr.resize(psize);
    random_generator rnd(rank);
    for (int i = 0; i < psize; ++i)
    {
        arr[i].init(env, rnd);
        arr[i].assign(*sol[i]);
    }
}


//EOF!
